﻿//Created by Action Script Viewer - http://www.buraks.com/asv
package Classes.sim {
    import Engine.Helpers.*;
    import Classes.*;
    import __AS3__.vec.*;
    import Modules.bandits.*;
    import Modules.stats.data.*;
    import Modules.stats.*;
    import Modules.ships.cruise.*;
    import Classes.announcers.*;
    import com.adobe.utils.*;

    public class CitySim implements IGameWorldStateObserver, IStatsTarget {

        public static const HAPPINESS_GOOD:int = 0;
        public static const HAPPINESS_NEUTRAL:int = 1;
        public static const HAPPINESS_BAD:int = 2;

        protected var m_lowestPopulationYield:int = -1;
        protected var m_notificationStateObserver:NotificationStateObserver;
        protected var m_npcMgr:NPCManager;
        protected var m_roadMgr:RoadManager;
        protected var m_friendVisitMgr:FriendVisitManager;
        protected var m_waterMgr:WaterManager;
        protected var m_trainMgr:TrainManager;
        protected var m_lotMgr:LotManager;
        protected var m_pickupMgr:PickupManager;
        protected var m_nghbrNavNgr:NeighborNavigationManager;
        protected var m_miniQuestManager:MiniQuestManager;
        protected var m_bizBatchManager:BusinessVisitBatchManager;
        protected var m_banditManager:BanditManager;
        protected var m_cruiseShipManager:CruiseShipManager;
        protected var m_poiMgr:POIManager;
        protected var m_announcerManager:AnnouncerManager;
        protected var m_population:int;
        protected var m_populationCap:int;
        protected var m_potentialPopulation:int;
        protected var m_stateObservers:Array;

        public function CitySim(_arg1:GameWorld){
            this.m_notificationStateObserver = new NotificationStateObserver(_arg1);
            this.m_roadMgr = new RoadManager(_arg1);
            this.m_waterMgr = new WaterManager(_arg1);
            this.m_lotMgr = new LotManager(_arg1);
            this.m_npcMgr = new NPCManager(_arg1);
            this.m_pickupMgr = new PickupManager(_arg1);
            this.m_nghbrNavNgr = new NeighborNavigationManager(_arg1);
            this.m_poiMgr = new POIManager();
            this.m_friendVisitMgr = new FriendVisitManager(_arg1);
            this.m_stateObservers = new Array();
            this.m_miniQuestManager = new MiniQuestManager(_arg1);
            this.m_bizBatchManager = new BusinessVisitBatchManager(_arg1);
            this.m_banditManager = new BanditManager(_arg1);
            this.m_cruiseShipManager = new CruiseShipManager(_arg1);
            this.m_announcerManager = new AnnouncerManager(_arg1);
            _arg1.addObserver(this);
        }
        public function loadObject(_arg1:Object):void{
            var _local2:IPopulationStateObserver;
            this.m_population = _arg1.population;
            this.m_populationCap = _arg1.populationCap;
            this.m_potentialPopulation = _arg1.potentialPopulation;
            for each (_local2 in this.m_stateObservers) {
                _local2.onPopulationInit(this.getPopulation(), this.getScaledPopulation(), this.getTotalPopulation());
                _local2.onPopulationChanged(this.getPopulation(), this.getPopulation(), this.getScaledPopulation(), this.getTotalPopulation());
                _local2.onPotentialPopulationChanged(this.getPotentialPopulation(), this.getTotalPopulation());
                _local2.onPopulationCapChanged(this.getPopulationCap());
            };
        }
        public function getStatsCounterObject():Vector.<StatsCountData>{
            var _local1:Vector.<StatsCountData> = new Vector.<StatsCountData>();
            _local1.push(new StatsCountData(new StatsOntology("population"), this.getScaledPopulation()));
            _local1.push(new StatsCountData(new StatsOntology("population_max"), this.getScaledPopulationCap()));
            return (_local1);
        }
        public function initialize():void{
            if (this.m_trainMgr){
                this.m_trainMgr.stopObserving();
            };
            this.m_trainMgr = new TrainManager(Global.world);
        }
        public function cleanUp():void{
        }
        public function onGameLoaded(_arg1:Object):void{
        }
        public function get npcManager():NPCManager{
            return (this.m_npcMgr);
        }
        public function get roadManager():RoadManager{
            return (this.m_roadMgr);
        }
        public function get friendVisitManager():FriendVisitManager{
            return (this.m_friendVisitMgr);
        }
        public function get waterManager():WaterManager{
            return (this.m_waterMgr);
        }
        public function get trainManager():TrainManager{
            return (this.m_trainMgr);
        }
        public function get lotManager():LotManager{
            return (this.m_lotMgr);
        }
        public function get pickupManager():PickupManager{
            return (this.m_pickupMgr);
        }
        public function get neighborNavigationManager():NeighborNavigationManager{
            return (this.m_nghbrNavNgr);
        }
        public function get poiManager():POIManager{
            return (this.m_poiMgr);
        }
        public function get miniQuestManager():MiniQuestManager{
            return (this.m_miniQuestManager);
        }
        public function get businessVisitBatchManager():BusinessVisitBatchManager{
            return (this.m_bizBatchManager);
        }
        public function get banditManager():BanditManager{
            return (this.m_banditManager);
        }
        public function get cruiseShipManager():CruiseShipManager{
            return (this.m_cruiseShipManager);
        }
        public function get announcerManager():AnnouncerManager{
            return (this.m_announcerManager);
        }
        public function addObserver(_arg1:IPopulationStateObserver):void{
            if (!ArrayUtil.arrayContainsValue(this.m_stateObservers, _arg1)){
                this.m_stateObservers.push(_arg1);
            };
        }
        public function removeObserver(_arg1:IPopulationStateObserver):void{
            ArrayUtil.removeValueFromArray(this.m_stateObservers, _arg1);
        }
        public function onResourceChange(_arg1:MapResource, _arg2:Vector3, _arg3:Vector3):void{
            this.m_npcMgr.updateBuildingCaches();
            if (Global.franchiseManager.placementMode == false){
                Global.player.commodities.updateCapacities();
            };
        }
        public function toggleDebugRoadOverlay():void{
            this.m_roadMgr.showOverlay(!(this.m_roadMgr.isShowingOverlay));
        }
        private function numberObjects(_arg1:Class):int{
            var _local4:*;
            var _local2:int;
            var _local3:Array = Global.world.getObjects();
            for each (_local4 in _local3) {
                if ((_local4 is _arg1)){
                    _local2++;
                };
            };
            return (_local2);
        }
        public function getPopulation():int{
            return (this.m_population);
        }
        public function getPopulationCap():int{
            return ((this.m_populationCap + Global.gameSettings.getInt("initPopulationCap", 5)));
        }
        public function getScaledPopulation():int{
            return ((this.m_population * Global.gameSettings.getNumber("populationScale", 1)));
        }
        public function getScaledPopulationCap():int{
            return ((this.getPopulationCap() * Global.gameSettings.getNumber("populationScale", 1)));
        }
        public function applyPopulationScale(_arg1:Number):Number{
            return ((_arg1 * Global.gameSettings.getNumber("populationScale", 1)));
        }
        public function getRequiredPopulationCap(_arg1:Item):int{
            switch (_arg1.type){
                case "business":
                    return (this.applyPopulationScale(Math.ceil(((this.getTotalBusinesses() + 1) / Global.gameSettings.getNumber("businessLimitByPopulationMax")))));
                default:
                    return (this.applyPopulationScale((this.getTotalPopulation() + _arg1.populationBase)));
            };
        }
        public function getRequiredNonTotalPopulationCap(_arg1:Item):int{
            switch (_arg1.type){
                case "business":
                    return (this.getRequiredPopulationCap(_arg1));
                default:
                    return (this.applyPopulationScale((this.getPopulation() + _arg1.populationBase)));
            };
        }
        public function getPotentialPopulation():int{
            return (this.m_potentialPopulation);
        }
        public function getTotalPopulation():int{
            return ((this.m_population + this.m_potentialPopulation));
        }
        public function getTotalBusinesses():int{
            var _local4:ConstructionSite;
            var _local1:int = Global.world.getObjectsByTypes([WorldObjectTypes.BUSINESS]).length;
            var _local2:Array = Global.world.getObjectsByTypes([WorldObjectTypes.CONSTRUCTION_SITE]);
            var _local3:int;
            for each (_local4 in _local2) {
                if (_local4.targetClass == Business){
                    _local3++;
                };
            };
            return ((_local1 + _local3));
        }
        public function recomputePopulationCap(_arg1:GameWorld):void{
            var _local4:Municipal;
            var _local5:int;
            var _local6:IPopulationStateObserver;
            var _local2:int = this.m_populationCap;
            this.m_populationCap = 0;
            var _local3:Array = _arg1.getObjectsByClass(Municipal);
            for each (_local4 in _local3) {
                _local5 = _local4.getPopulationCapYield();
                this.m_populationCap = (this.m_populationCap + _local5);
            };
            if (this.m_populationCap != _local2){
                for each (_local6 in this.m_stateObservers) {
                    _local6.onPopulationCapChanged(this.getPopulationCap());
                };
            };
        }
        public function recomputePopulation(_arg1:GameWorld, _arg2:Boolean=true):void{
            var _local5:Residence;
            var _local6:int;
            var _local7:IPopulationStateObserver;
            var _local3:int = this.m_population;
            this.m_population = 0;
            var _local4:Array = _arg1.getObjectsByClass(Residence);
            for each (_local5 in _local4) {
                _local6 = _local5.getPopulationYield();
                this.m_population = (this.m_population + _local6);
            };
            if (_arg2){
                for each (_local7 in this.m_stateObservers) {
                    _local7.onPopulationChanged(this.getPopulation(), (this.m_population - _local3), this.getScaledPopulation(), this.getTotalPopulation());
                };
            };
        }
        public function recomputePotentialPopulation(_arg1:GameWorld):void{
            var _local4:ConstructionSite;
            var _local5:Item;
            var _local6:int;
            var _local7:IPopulationStateObserver;
            var _local2:int = this.m_potentialPopulation;
            this.m_potentialPopulation = 0;
            var _local3:Array = _arg1.getObjectsByClass(ConstructionSite);
            for each (_local4 in _local3) {
                if (_local4.targetClass == Residence){
                    _local5 = Global.gameSettings.getItemByName(_local4.targetName);
                    _local6 = _local5.populationBase;
                    this.m_potentialPopulation = (this.m_potentialPopulation + _local6);
                };
            };
            if (this.m_potentialPopulation != _local2){
                for each (_local7 in this.m_stateObservers) {
                    _local7.onPotentialPopulationChanged(this.getPotentialPopulation(), this.getTotalPopulation());
                };
            };
        }
        public function getHappinessState():int{
            var _local1:Number = Global.gameSettings.getNumber("happyPopulationCutoff", 0.65);
            var _local2:Number = Global.gameSettings.getNumber("sadPopulationCutoff", 0.85);
            var _local3:Number = (this.getPopulation() / this.getPopulationCap());
            if (_local3 < _local1){
                return (HAPPINESS_GOOD);
            };
            if (_local3 < _local2){
                return (HAPPINESS_NEUTRAL);
            };
            return (HAPPINESS_BAD);
        }
        protected function findLowestPopulationYield():void{
            var _local3:Item;
            this.m_lowestPopulationYield = -1;
            var _local1:Array = Global.gameSettings.getItemsByType("residence");
            var _local2:int;
            while (_local2 < _local1.length) {
                _local3 = (_local1[_local2] as Item);
                if ((((this.m_lowestPopulationYield == -1)) || ((_local3.populationBase < this.m_lowestPopulationYield)))){
                    this.m_lowestPopulationYield = _local3.populationBase;
                };
                _local2++;
            };
        }

    }
}//package Classes.sim 
